//
//  QSSingleton.h
//  test
//
//  Created by Song on 2016/11/17.
//  Copyright © 2016年 Song. All rights reserved.
//

#ifndef QSSingleton_h
#define QSSingleton_h

#pragma mark - 单例宏
// 1. 解决.h文件
#define singletonInterface(className) \
+ (instancetype)shared##className;\
+ (void)destroyInstance;\

// 2. 解决.m文件
// 判断 是否是 ARC
#if __has_feature(objc_arc)
#define singletonImplementation(className) \
static id instance = nil; \
static dispatch_once_t onceToken1; \
static dispatch_once_t onceToken2; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
dispatch_once(&onceToken1, ^{ \
if(instance == nil){\
instance = [super allocWithZone:zone]; \
}\
}); \
return instance; \
} \
+ (instancetype)shared##className { \
dispatch_once(&onceToken2, ^{ \
if(instance == nil){\
instance = [[self alloc] init]; \
}\
}); \
return instance; \
} \
- (id)copyWithZone:(NSZone *)zone { \
return instance; \
}\
+ (void)destroyInstance {\
instance = nil;\
onceToken1 = 0;\
onceToken2 = 0;\
}
#else
// MRC 部分
#define singletonImplementation(className) \
static id instance = nil; \
static dispatch_once_t onceToken1; \
static dispatch_once_t onceToken2; \
+ (instancetype)allocWithZone:(struct _NSZone *)zone { \
static dispatch_once_t onceToken; \
dispatch_once(&onceToken, ^{ \
if(instance == nil){\
instance = [super allocWithZone:zone]; \
}\
}); \
return instance; \
} \
+ (instancetype)shared##className { \
dispatch_once(&onceToken, ^{ \
if(instance == nil){\
instance = [[self alloc] init]; \
}\
}); \
return instance; \
} \
- (id)copyWithZone:(NSZone *)zone { \
return instance; \
} \
- (oneway void)release {} \
- (instancetype)retain {return instance;} \
- (instancetype)autorelease {return instance;} \
- (NSUInteger)retainCount {return ULONG_MAX;}\
+ (void)destroyInstance {\
[instance release];\
instance = nil;\
onceToken1 = 0;\
onceToken2 = 0;\
}

#endif

#endif /* QSSingleton_h */
